<template>
  <div class="paper">
    <!-- 答题卡 -->
    <div class="paper-left">
      <el-card shadow="never" class="paper-left-top">
        <!-- <el-avatar size="large"/> -->
        <div class="userContent">
          <img
            :src="userStore.avaterUrl"
            class="avatar"
            v-if="userStore.avaterUrl"
          />
          <img :src="userimg" class="avatar default" v-else />
          <span class="paper-left-top-username">
            <span style="margin-bottom: 7px"> {{ user.name }}</span>
            <span style="margin-top: 7px"> {{ user.orgName }}</span>
          </span>
        </div>
        <div class="paper-left-top-statis">
          <div>
            <Iconfont
              icon="icon-jiangbei"
              :size="20"
              color="#F6961E;"
              :width="30"
              :height="42"
              :radius="5"
              background-color="#FDF3E7"
            />
            <div style="flex-direction: column">
              <span
                class="paper-left-top-statis-value"
                v-bind:class="{
                  jg: myExam.answerState == 1,
                  nojg: myExam.answerState == 2,
                }"
                >{{ scoreShow ? myExam.totalScore + "分" : "-" }}</span
              >
              <span class="paper-left-top-statis-txt">得分</span>
            </div>
          </div>
          <!-- <div>
                        <Iconfont icon="icon-shijianxuanzhong" :size="20" color="#F6961E;" :width="30" :height="30" :radius="5" background-color="#FDF3E7" />
                        <span class="paper-left-top-statis-value">{{ myExam.state === 3 ? timeDiff(myExam.answerStartTime, myExam.answerEndTime) : '-'}}</span>
                        <span class="paper-left-top-statis-txt">答题用时</span>
                    </div> -->
          <div>
            <Iconfont
              icon="icon-approval-fulll"
              :size="20"
              color="#05CAC1;"
              :width="30"
              :height="42"
              :radius="5"
              background-color="#E3F3FF"
            />
            <div style="flex-direction: column">
              <span
                class="paper-left-top-statis-value"
                v-bind:class="{
                  jg: myExam.answerState == 1,
                  nojg: myExam.answerState == 2,
                }"
                >{{
                  scoreShow
                    ? dictStore.getValue("ANSWER_STATE", myExam.answerState)
                    : "-"
                }}</span
              >
              <span class="paper-left-top-statis-txt">成绩</span>
            </div>
          </div>
          <!-- <div>
                        <Iconfont icon="icon-shijianxuanzhong" :size="20" color="#327EF6;" :width="30" :height="30" :radius="5" background-color="#E3F3FF" />
                        <span class="paper-left-top-statis-value">{{ rankShow ? `${myExam.no || '-'} / ${myExam.userNum}` : `-` }}</span>
                        <span class="paper-left-top-statis-txt">排名</span>
                    </div> -->
        </div>
        <div v-if="isAnswer" class="paper-left-top-time">
          <CountDown
            :expireTime="examEndTime"
            preTxt="距结束："
            :remind="300"
            @end="finish"
            @remind="exam.color = 'var(--el-color-danger)'"
            :color="exam.color"
          ></CountDown>
        </div>
        <a-popconfirm
          :title="userAnswerNum==questionNum?'是否确认交卷？':`还有${questionNum-userAnswerNum}题未答,是否确认交卷？`"
          ok-text="交卷"
          cancel-text="取消"
          @confirm="finish"
        >
          <el-button v-if="isAnswer" type="primary">交卷</el-button>
        </a-popconfirm>

        <fontSet />

        <el-button type="primary" plain @click="$router.go(-1)">返回</el-button>
      </el-card>
      <el-card
        shadow="never"
        class="paper-left-bottom"
        style="background-color: #fafafa"
      >
        <el-divider> 答题卡 </el-divider>
        <el-scrollbar :height="calculateHeight">
          <template v-for="examQuestion in examQuestions">
            <el-button
            v-if="examQuestion?.type !== 1"
              :data-no="examQuestion.no"
              :type="errMark(examQuestion).type"
              :plain="errMark(examQuestion).plain"
              @click="toNav(examQuestion)"
              >{{ examQuestion.no }}</el-button
            >
          </template>
        </el-scrollbar>
      </el-card>
    </div>
    <!-- 试卷 -->
    <el-scrollbar height="calc(100vh - 40px)" class="paper-right">
      <el-card shadow="never" style="background-color: #fafafa">
        <!-- 右上角显示打分 -->
        <div class="paper-right-score" v-if="scoreShow">
          <span class="paper-right-score-value">{{ myExam.totalScore }}</span>
          <span class="iconfont icon-fenshudixian"></span>
        </div>
        <!-- 试卷名称 -->
        <div class="paper-right-title" style="background-color: #fafafa">
          <el-input
            :value="exam.name"
            :maxlength="16"
            placeholder=""
            :readonly="true"
          />
        </div>
        <!-- 试题列表 -->
        <template v-for="(examQuestion, index) in examQuestions" :key="index">
          <div v-if="examQuestion.type === 1" class="paper-right-chapter">
            <el-input
              :value="examQuestion.chapterName"
              maxlength="14"
              placeholder="请输入章节名称"
              :readonly="true"
            />
            <el-input
              v-if="examQuestion.chapterTxt"
              :value="examQuestion.chapterTxt"
              type="textarea"
              maxlength="128"
              :autosize="{ minRows: 1 }"
              resize="none"
              placeholder="请输入章节描述"
              :readonly="true"
            />
          </div>
          <Question
            v-else
            :no="examQuestion.no"
            :type="examQuestion.questionType || 1"
            :markType="examQuestion.markType || 1"
            :title="examQuestion.title || ''"
            :score="examQuestion.score || 1"
            :answers="examQuestion.answers"
            :userAnswers="examQuestion.userAnswers"
            :userScore="examQuestion.userScore"
            :options="examQuestion.options"
            :editable="isAnswer"
            @change="(answers: string[]) => answerUpdate(examQuestion, answers)"
            :errShow="scoreShow"
          >
            <template
              #bottom-right
              v-if="
                myExam.state === 3 ||
                (myExam.state === 1 && myExam.markState === 3)
              "
              ><!-- 已交卷或（未考试已阅卷） -->
              <el-tooltip
                placement="top"
                effect="light"
                :content="answerShow(examQuestion) || '稍后查看答案'"
                popper-class="popper-class"
                raw-content
              >
                <el-button type="success" size="small">标准答案</el-button>
              </el-tooltip>
            </template>
          </Question>
        </template>
      </el-card>
    </el-scrollbar>
    <a-modal
      v-model:open="open"
      title="确认开始考试"
      @cancel="handleCancel"
      @ok="handleOk"
      ok-text="确认"
      cancel-text="取消"
    >
      <p>是否开始考试？</p>
    </a-modal>
  </div>
</template>
<script lang="ts" setup>
import http from "@/request";
import { computed, onMounted, onUnmounted, reactive, ref, nextTick } from "vue";
import Question from "@/components/question/Question.vue";
import type { ExamQuestion } from "@/stores/exam";
import _ from "lodash";
import CountDown from "@/components/CountDown.vue";
import dayjs from "dayjs";
import { ElMessageBox, type Action } from "element-plus";
import { UserOutlined } from "@ant-design/icons-vue";
import { useRouter, useRoute } from "vue-router";
import { useDictStore } from "@/stores/dict";
import fontSet from "@/components/fontSet.vue";
import userimg from "@/assets/image/user.png";
import { noticStore } from "@/stores/notic";
import { useUserStore } from "@/stores/user";

// 定义变量
const userStore = useUserStore();
const noticFn = noticStore();
const route = useRoute();
const router = useRouter();
const dictStore = useDictStore(); // 字典缓存
const examQuestions = ref([] as ExamQuestion[]); // 试卷信息
const exam = reactive({
  // 考试信息
  id: 0, // 考试ID
  name: "", // 试卷名称
  color: "", // 倒计时颜色
  markState: 0, // 阅卷状态
  scoreState: 0, // 分数状态
  rankState: 0, // 排名状态
});
const examEndTime = ref(); // 考试结束时间（用reactive必须new Date()，会造成问题）
const myExam = reactive({
  // 我的考试信息
  totalScore: 0, //总分
  answerStartTime: new Date(), // 答题开始时间
  answerEndTime: new Date(), // 答题结束时间
  markStartTime: new Date(), // 阅卷开始时间
  markEndTime: new Date(), // 阅卷结束时间
  state: 0, // 考试状态
  markState: 0, // 阅卷状态
  answerState: 0, // 答题状态
  no: 0, // 用户排名
  userNum: 0, // 用户数量
  myAnswerStartTime: null,
  examPassTime: null,
});
const user = reactive({
  // 用户信息
  name: "", // 姓名
  orgName: "", // 机构名称
});
const open = ref(false);

const handleOk = async (e) => {
  open.value = false;
  let {
    data: { code },
  } = await http.post("myExamMock/startExam", {
    examId: exam.id,
  });
  if (code == 200) {
    examEndTime.value = dayjs(myExam.examStartTime)
      .add(myExam.examPassTime, "m")
      .toDate();
  }
};
const handleCancel = () => {
  open.value = false;
  //返回上一个页面
  router.go(-1);
};
// 组件挂载完成后，执行如下方法
onMounted(async () => {
  // 获取机构信息
  let {
    data: { data: data2 },
  } = await http.post("user/get", {});
  user.name = data2.name;
  user.orgName = data2.orgName;

  // 获取我的考试信息
  exam.id = parseInt(route.params.examId as string);
  let {
    data: { data },
  } = await http.post("myExamMock/get", { examId: exam.id });
  let {
    data: { data: dataTime },
  } = await http.post("login/sysTime", {});

  exam.name = data.examName;
  exam.markState = data.examMarkState;
  exam.scoreState = data.examScoreState;
  exam.rankState = data.examRankState;
  let examStartTime = data.answerStartTime || new Date(dataTime);

  if (data.state == 1) {
    myExam.myAnswerStartTime = examStartTime;
    myExam.examPassTime = data.examPassTime;
    let {
      data: { code },
    } = await http.post("myExamMock/startExam", {
      examId: exam.id,
    });
    if (code == 200) {
      examEndTime.value = dayjs(examStartTime)
        .add(myExam.examPassTime, "m")
        .toDate();
    }
  } else {
    examEndTime.value = dayjs(examStartTime)
      .add(data.examPassTime, "m")
      .toDate();
  }

  myExam.totalScore = data.totalScore;
  myExam.answerStartTime = dayjs(
    data.answerStartTime,
    "YYYY-MM-DD HH:mm:ss"
  ).toDate();
  myExam.answerEndTime = dayjs(
    data.answerEndTime,
    "YYYY-MM-DD HH:mm:ss"
  ).toDate();
  myExam.markStartTime = dayjs(
    data.markStartTime,
    "YYYY-MM-DD HH:mm:ss"
  ).toDate();
  myExam.markEndTime = dayjs(data.markEndTime, "YYYY-MM-DD HH:mm:ss").toDate();
  myExam.state = data.state;
  myExam.markState = data.markState;
  myExam.answerState = data.answerState;
  myExam.no = data.no;
  myExam.userNum = data.userNum;

  // 获取试卷信息
  let {
    data: { data: data1 },
  } = await http.post("myExamMock/paper", { examId: exam.id });
  let no = 1;
  examQuestions.value = data1.map((examQuestion: ExamQuestion) => {
    if (examQuestion.type === 2) {
      // 处理题号
      examQuestion.no = no++;
    }
    return examQuestion;
  });

  let targetExam = noticFn?.mockInfo?.find((item) => item.id == exam.id);
  if (targetExam) {
    //延时，防止获取不到试卷
    await nextTick();
    toNav(examQuestions.value[targetExam.no - 1]); // 假设每场考试都有一个 paperIndex 属性存储试卷索引
    const button = document.querySelector(`[data-no="${targetExam.no}"]`);
    // 如果找到了按钮元素
    if (button) {
      // 将按钮滚动到可视区域内
      button.scrollIntoView({ behavior: "smooth", block: "center" });
    }
  } else {
    noticFn.mockInfo.push({
      id: exam.id,
      no: 0,
    });
  }
  // //如果超时就自动提交
  // if(data.answerStartTime!=null &&
  //    data.state!=3 &&
  // isChaoShi(new Date(data.answerStartTime),new Date(dataTime),data.examPassTime)){
  //     finish()
  //     return
  // }
});

const calculateHeight = computed(() => {
  if (myExam.markState == 3) {
    return `calc(100vh - 362px)`; // 自定义高度
  } else {
    return `calc(100vh - 456px)`; // 默认高度，不减去410px
  }
});
// 组件卸载完成后，执行如下方法
onUnmounted(() => {});

// 计算属性
const isAnswer = computed(
  () => (myExam.state === 1 && myExam.markState != 3) || myExam.state === 2
); // 是否答题。未考试且未阅卷显示（未考试且考试结束时间到，后台会处理成未考试且已阅卷）；考试中显示
const scoreShow = computed(() => {
  // 分数显示（后端已经数据过滤掉，这里控制只是好理解）
  return (
    (exam.scoreState == 1 && exam.markState == 3) || // 如果是考试结束后显示成绩，需要等到考试结束
    (exam.scoreState == 3 && myExam.markState == 3)
  ); // 如果是交卷后显示成绩，需要等到该试卷阅卷完成。比如主观题没阅卷，得不到总分，得不到是否及格
});
const rankShow = computed(() => exam.rankState === 1);

// 答题
const answerUpdate = _.debounce(async function (examQuestion, answers) {
  // _.debounce返回的包装后的函数，所以能正常传参
  let {
    data: { code, data },
  } = await http.post("myExamMock/answer", {
    examId: exam.id,
    questionId: examQuestion.questionId,
    answers: answers,
  });
  if (code != 200) {
    // 答题失败也不要清空答案，比如问答题清空就尴尬了
    return;
  }
  //更新该场考试的答题index
  noticFn.mockInfo[
    noticFn.mockInfo.findIndex((item) => item.id == exam.id)
  ].no = examQuestion.no;
  //在examQuestions找到这道题，将答案赋值
  examQuestions.value.forEach((item) => {
    if (item.questionId == examQuestion.questionId) {
      item.userAnswers = answers;
    }
  })
}, 500); // 延时一秒体验不好，填完直接返回没提交

// 交卷
async function finish() {
  let {
    data: { code, data },
  } = await http.post("myExamMock/finish", { examId: exam.id });
  if (code !== 200) {
    return;
  }
  //交卷，清空答题index
  noticFn.mockInfo[
    noticFn.mockInfo.findIndex((item) => item.id == exam.id)
  ].no = 1;
  examEnd();
}

// 考试结束
function examEnd() {
  ElMessageBox.alert("考试成功", "提示消息", {
    confirmButtonText: "确定",
    callback: async (action: Action) => {
      // 获取我的考试信息
      exam.id = parseInt(route.params.examId as string);
      let {
        data: { data },
      } = await http.post("myExamMock/get", { examId: exam.id });
      exam.name = data.examName;
      exam.markState = data.examMarkState;
      exam.scoreState = data.examScoreState;
      exam.rankState = data.examRankState;
      examEndTime.value = dayjs(
        data.examEndTime,
        "YYYY-MM-DD HH:mm:ss"
      ).toDate();

      myExam.totalScore = data.totalScore;
      myExam.answerStartTime = dayjs(
        data.answerStartTime,
        "YYYY-MM-DD HH:mm:ss"
      ).toDate();
      myExam.answerEndTime = dayjs(
        data.answerEndTime,
        "YYYY-MM-DD HH:mm:ss"
      ).toDate();
      myExam.markStartTime = dayjs(
        data.markStartTime,
        "YYYY-MM-DD HH:mm:ss"
      ).toDate();
      myExam.markEndTime = dayjs(
        data.markEndTime,
        "YYYY-MM-DD HH:mm:ss"
      ).toDate();
      myExam.state = data.state;
      myExam.markState = data.markState;
      myExam.answerState = data.answerState;
      myExam.no = data.no;
      myExam.userNum = data.userNum;

      // 获取试卷信息
      let {
        data: { data: data1 },
      } = await http.post("myExamMock/paper", { examId: exam.id });
      let no = 1;
      examQuestions.value = data1.map((examQuestion: ExamQuestion) => {
        if (examQuestion.type === 2) {
          // 处理题号
          examQuestion.no = no++;
        }
        return examQuestion;
      });
    },
  });
}

// 答题导航
function toNav(examQuestion: ExamQuestion) {
  if (examQuestion) {
    (
      document.querySelector(`#question-${examQuestion.no}`) as HTMLElement
    ).scrollIntoView(true);
  }
}

// 时间差值
function timeDiff(startTime: Date, endTime: Date) {
  let h = Math.floor(
    (endTime.getTime() - startTime.getTime()) / 1000 / 60 / 60
  );
  let m = Math.floor(
    ((endTime.getTime() - startTime.getTime()) / 1000 / 60) % 60
  );
  let s = Math.floor(((endTime.getTime() - startTime.getTime()) / 1000) % 60);
  return `${("0" + h).slice(-2)}:${("0" + m).slice(-2)}:${("0" + s).slice(-2)}`;
}

// 时间差值的分钟数
function isChaoShi(startTime: Date, endTime: Date, passTime: number) {
  let s = (endTime.getTime() - startTime.getTime()) / 1000;
  return s > passTime * 60;
}
const questionNum = computed(() => {
  // 试题数量
  return examQuestions.value.reduce((total, examQuestion) => {
    return examQuestion.type === 2 ? total + 1 : total;
  }, 0);
});
const userAnswerNum = computed(() => {
  // 用户答题数量
  return examQuestions.value.reduce((total, examQuestion) => {
    if (
      examQuestion.type === 2 &&
      examQuestion.userAnswers?.some((userAnswer) => userAnswer.length > 0)
    ) {
      return total + 1;
    }
    return total;
  }, 0);
});
function errMark(examQuestion: ExamQuestion) {
  let question = examQuestion;
  if (!question.userAnswers?.length) {
    // 如果没有作答，默认颜色
    return { type: "", plain: false };
  } else if (myExam.markState == 3 && question.userScore!==1){
    return { type: "danger", plain: true };
  } else {
    return { type: "primary", plain: true };
  }
}
function answerShow(examQuestion: ExamQuestion) {
  if (
    examQuestion.questionType === 1 || // 单选
    examQuestion.questionType === 4 || // 判断
    (examQuestion.questionType === 5 && examQuestion.markType === 2)
  ) {
    // 主观问答
    return (
      examQuestion.answers &&
      examQuestion.answers[0] &&
      examQuestion.answers[0].replaceAll("\n", "<br/>")
    );
  }
  if (examQuestion.questionType === 2) {
    // 多选
    return examQuestion.answers?.toString().replaceAll(",", "");
  }

  if (
    examQuestion.questionType === 3 || // 填空
    (examQuestion.questionType === 5 && examQuestion.markType === 1)
  ) {
    // 客观问答
    let answerFormat = "";
    examQuestion.answers?.forEach((answer, index) => {
      answerFormat += `${examQuestion.questionType === 3 ? "填空" : "关键词"}${
        index + 1
      }：${answer.replaceAll("\n", "、")}<br/>`;
    });

    return answerFormat;
  }
}
</script>


<style lang="scss" scoped>
.paper {
  flex: 1;
  display: flex;
  margin-bottom: 10px;
  .paper-left {
    width: 320px;
    display: flex;
    flex-direction: column;
    .paper-left-top {
      margin-bottom: 10px;
      background-color: #fafafa;
      :deep(.el-card__body) {
        display: flex;
        flex-direction: column;
        align-items: center;
        padding: 10px 10px;
        .el-avatar {
          border: 2px solid var(--el-color-primary);
          margin-bottom: 10px;
        }
        .paper-left-top-username {
          font-size: 16px;
          font-weight: bold;
          color: #333;
        }
        .paper-left-top-statis {
          display: flex;
          width: 100%;
          div {
            flex: 1;
            margin: auto;
            display: flex;
            align-items: center;
            .paper-left-top-statis-value {
              font-size: 14px;
              font-weight: bold;
              display: block;
              text-align: center;
            }
            .jg {
              color: #25b864;
            }
            .nojg {
              color: #ff0000;
            }
            .paper-left-top-statis-txt {
              font-size: 14px;
              font-weight: bold;
              color: #333;
              display: block;
              text-align: center;
            }
          }
        }
        .paper-left-top-time {
          border: 1px dashed var(--el-color-primary);
          padding: 5px;
          margin-top: 20px;
          width: 96%;
          span {
            font-weight: bold;
            font-size: 14px;
            color: var(--el-color-primary);
            margin: auto;
            display: block;
            text-align: center;
          }
        }
        .el-button {
          width: 100%;
          margin-top: 10px;
          margin-left: 0px;
        }
      }
    }

    .paper-left-bottom {
      .el-divider--horizontal {
        margin: 15px 0px 20px 0px;
      }
      .el-button {
        height: 50px;
        width: 50px;
        padding: 0;
        margin: 2px;
        font-size: 18px;
      }
      .paper-left-bottom-chapter {
        font-size: 13px;
        font-weight: bold;
        margin: 5px 0px;
        cursor: pointer;
      }
    }
  }

  :deep(.paper-right) {
    flex: 1;
    .el-card {
      min-height: calc(100vh - 50px);
      margin-left: 10px;
      position: relative;
      &:hover {
        .paper-right-toolbar {
          display: block;
        }
      }
      .paper-right-toolbar {
        position: absolute;
        right: 10px;
        top: 5px;
        display: none;
        z-index: 2;
      }

      .paper-right-score {
        position: absolute;
        right: 30px;
        top: 30px;
        z-index: 2;

        display: flex;
        flex-direction: column;
        color: red;
        font-size: 26px;

        .iconfont {
          font-size: 58px;
          line-height: 30px;
        }
        .paper-right-score-value {
          text-align: center;
        }
      }

      .paper-right-title {
        margin-top: 10px;

        .el-input__wrapper {
          box-shadow: initial;
          background-color: #fafafa;
          .el-input__inner {
            background-color: #fafafa;
            text-align: center;
            font-size: 24px;
            font-weight: bold;
            color: #333;
          }
        }
      }

      .paper-right-chapter {
        padding: 0px 20px;
        position: relative;
        &:hover {
          .el-button {
            display: inline-block;
          }
        }
        .el-input__wrapper {
          box-shadow: initial;
          background-color: #fafafa;
          .el-input__inner {
            background-color: #fafafa;
            font-size: 16px;
            font-weight: bold;
          }
        }
        .el-textarea__inner {
          box-shadow: initial;
        }
        .el-button {
          position: absolute;
          bottom: 5px;
          right: 5px;
          display: none;
        }
        .el-form-item {
          // 校验通过时，恢复和章节描述的距离
          margin-bottom: 0;
          &.is-error {
            margin-bottom: 18px;
          }
        }
        .el-form-item__error {
          margin-left: 12px;
        }
      }
    }
  }
}
</style>
<style lang="scss" scoped>
.popper-class {
  max-width: 800px;
}
.el-radio__input.is-disabled + span.el-radio__label {
  color: #333;
  font-size: 15px;
}

.userContent {
  display: flex;
  align-items: center;
  margin-bottom: 10px;
  width: 96%;
  height: 80px;
}
.paper-left-top-username {
  display: flex;
  flex-direction: column;
}
.avatar {
  width: 60px;
  height: 80px;
  object-fit: cover; /* 图片填充头像框 */
  margin-right: 6px;
}
.default {
  margin-top: -20px;
}
.avatar-uploader-icon {
  font-size: 28px;
  margin-right: 6px;
}
</style>